unit DrawObjectTests;

interface

uses
  TestFrameWork, DrawObject, Graphics;

type
  TTestDrawObject = class(TDrawObject)
  public
    constructor Create;

  end;

  TTestDrawObject2 = class(TDrawObject)
  private
    FTag: string;
  protected
    procedure InternalDraw; override;
    function InternalTestHit(X, Y: Double): Boolean; override;
  public
    constructor Create(Tag: string);
    property Next;
    property Parent;
    property Canvas;
    property StretchFactor;
  end;

  TMyCanvas = class(TCanvas)
  private
    FField: string;
  end;

  TDrawObjectTests = class(TTestCase)
  private
    FTestDrawObject: TTestDrawObject;
  protected
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure testDrawingSequence;
    procedure testDraw;
    procedure testDestroy;
    procedure testTestHit;
    procedure testCanvasProp;
    procedure testStretchFactorProp;
    procedure testMoveUp;
    procedure testMoveDown;
  end;

implementation
uses Classes, SysUtils, Forms, ExtCtrls;


{ TDrawObjectTests }

procedure TDrawObjectTests.SetUp;
begin
  inherited;
  FTestDrawObject := TTestDrawObject.Create;
end;

procedure TDrawObjectTests.TearDown;
begin
  inherited;
  FTestDrawObject.Free;
end;

procedure TDrawObjectTests.testCanvasProp;
var
  MyCanvas: TMyCanvas;
begin
  CheckEquals(False, Assigned(FTestDrawObject.Canvas));
  MyCanvas:= TMyCanvas.Create;
  try
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckSame(MyCanvas, FTestDrawObject.Canvas);
  finally
    MyCanvas.Free;
  end;
end;

procedure TDrawObjectTests.testDestroy;
var
CurObj: TTestDrawObject2;

begin
  CurObj:=FTestDrawObject.FirstSubObj as TTestDrawObject2;
  CurObj.Next.Free;         //2
  CurObj := CurObj.Next as TTestDrawObject2;
  CheckEquals('3', CurObj.FTag);
  CheckSame(FTestDrawObject.FirstSubObj, CurObj.Previous);
  CurObj.Next.Free;          //4
  CheckEquals('3', (FTestDrawObject.LastSubObj as TTestDrawObject2).FTag);
  FTestDrawObject.FirstSubObj.Free; //1
  FTestDrawObject.FirstSubObj.Free; //3
  CheckSame(nil, FTestDrawObject.FirstSubObj);
  CheckSame(nil, FTestDrawObject.LastSubObj);
end;

procedure TDrawObjectTests.testDraw;
var
  MyCanvas : TMyCanvas;
begin
  MyCanvas := TMyCanvas.Create;
  try
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('1234', MyCanvas.FField);
  finally
    MyCanvas.Free;
  end;
end;

procedure TDrawObjectTests.testDrawingSequence;
var
CurObj, PrevObj: TTestDrawObject2;
begin
  CurObj:= FTestDrawObject.FirstSubObj as TTestDrawObject2;     //1
  CheckSame(FTestDrawObject, CurObj.Parent);
  CheckSame(nil, CurObj.Previous);
  CheckEquals('1', CurObj.FTag);

  PrevObj := CurObj;
  CurObj:= CurObj.Next as TTestDrawObject2;               //2
  CheckSame(FTestDrawObject, CurObj.Parent);
  CheckSame(PrevObj, CurObj.Previous);
  CheckEquals('2', CurObj.FTag);

  PrevObj := CurObj;
  CurObj:= CurObj.Next as TTestDrawObject2;               //3
  CheckSame(FTestDrawObject, CurObj.Parent);
  CheckSame(PrevObj, CurObj.Previous);
  CheckEquals('3', CurObj.FTag);

  PrevObj := CurObj;
  CurObj:= CurObj.Next as TTestDrawObject2;               //4
  CheckSame(CurObj, FTestDrawObject.LastSubObj);
  CheckSame(FTestDrawObject, CurObj.Parent);
  CheckSame(PrevObj, CurObj.Previous);
  CheckSame(nil, CurObj.Next);
  CheckEquals('4', CurObj.FTag);
end;

procedure TDrawObjectTests.testMoveDown;
var
  MyCanvas : TMyCanvas;
  CurObj: TTestDrawObject2;
begin
  MyCanvas := TMyCanvas.Create;
  try
    CurObj := TTestDrawObject2(FTestDrawObject.FirstSubObj);
    CurObj := TTestDrawObject2(CurObj.Next);
    CurObj.MoveDown;
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('2134', MyCanvas.FField);
    CurObj := TTestDrawObject2(FTestDrawObject.FirstSubObj);
    CurObj.MoveDown;
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('21342134', MyCanvas.FField);
    CurObj := TTestDrawObject2(FTestDrawObject.LastSubObj);
    CurObj.MoveDown;
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('213421342143', MyCanvas.FField);

  finally
    MyCanvas.Free;
  end;
end;


procedure TDrawObjectTests.testMoveUp;
var
  MyCanvas : TMyCanvas;
  CurObj: TTestDrawObject2;
begin
  CheckSame(nil, FTestDrawObject.Parent);


  MyCanvas := TMyCanvas.Create;
  try
    CurObj := TTestDrawObject2(FTestDrawObject.FirstSubObj);
    CurObj := TTestDrawObject2(CurObj.Next);
    CurObj.MoveUp;
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('1324', MyCanvas.FField);
    CurObj := TTestDrawObject2(FTestDrawObject.FirstSubObj);
    CurObj.MoveUp;
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('13243124', MyCanvas.FField);
    CurObj := TTestDrawObject2(FTestDrawObject.LastSubObj);
    CurObj.MoveUp;
    FTestDrawObject.Draw(MyCanvas, 0, 0, 1);
    CheckEquals('132431243124', MyCanvas.FField);

  finally
    MyCanvas.Free;
  end;
end;


procedure TDrawObjectTests.testStretchFactorProp;
var
  MyCanvas: TMyCanvas;
begin
  MyCanvas:= TMyCanvas.Create;
  try
    FTestDrawObject.Draw(MyCanvas, 0, 0, 15);
    CheckEquals(15, FTestDrawObject.StretchFactor);
    FTestDrawObject.Draw(MyCanvas, 0, 0, 18);
    CheckEquals(18, FTestDrawObject.StretchFactor);
  finally
    MyCanvas.Free;
  end;
end;

procedure TDrawObjectTests.testTestHit;
var
  MyCanvas: TMyCanvas;
begin
  MyCanvas:= TMyCanvas.Create;
  try
    FTestDrawObject.Draw(MyCanvas, 0, 0, 15);
    CheckEquals('3', (FTestDrawObject.TestHit(0,0) as TTestDrawObject2).FTag);
  finally
    MyCanvas.Free;
  end;
end;

{ TTestDrawObject }

constructor TTestDrawObject.Create;
begin
  AddToQueue(TTestDrawObject2.Create('1'));
  AddToQueue(TTestDrawObject2.Create('2'));
  AddToQueue(TTestDrawObject2.Create('3'));
  AddToQueue(TTestDrawObject2.Create('4'));
end;

{ TTestDrawObject2 }

constructor TTestDrawObject2.Create(Tag: string);
begin
  FTag := Tag;
end;

procedure TTestDrawObject2.InternalDraw;
begin
  inherited;
  (Canvas as TMyCanvas).FField := (Canvas as TMyCanvas).FField + FTag;
end;

function TTestDrawObject2.InternalTestHit(X, Y: Double): Boolean;
begin
   Result := (FTag = '2') or (FTag = '3');

end;

initialization
  TestFramework.RegisterTest('TDrawObjectTests Suite',
    TDrawObjectTests.Suite);

end.

